package com.hrp.analyzer.core.model;

import com.hrp.analyzer.core.rule.CommonRule;
import com.hrp.analyzer.core.rule.RuleConstant;
import com.hrp.analyzer.model.Verifiable;
import com.hrp.analyzer.request.RequestParams;

import java.io.Serializable;
import java.util.Set;


/**
 * 目录规则
 * <pre>
 *     # 最小规则
 *     "toc": {
 *         "list": "匹配章节列表",
 *         "name": "章节名称",
 *         "url":  "章节的链接"
 *     }
 *     "toc":{
 *         "list": "匹配章节列表",
 *         "name": "章节名称",
 *         "url":  "章节的链接",
 *         "next": "下一页规则",
 *         "enableNext": ""是否允许下一页,
 *         "blackUrls": "黑名单链接",
 *         "filter": "允许章节过滤",
 *         "reserve": "章节逆序",
 *         "sort": "章节重排序",
 *     }
 * </pre>
 *
 * @author hrp
 * @date 2021/02/10 11:10
 */

public class TocRule implements Verifiable, Serializable {
    private static final long serialVersionUID = -6824834231883722483L;
    /**
     * 请求参数
     */
    private RequestParams params;
    /**
     * 章节列表
     */
    private CommonRule list;
    /**
     * 章节名称
     */
    private CommonRule name;
    /**
     * 章节链接
     */
    private CommonRule url;
    /**
     * 章节下一页规则（存在则会匹配下一页）
     */
    private CommonRule next = CommonRule.create("xpath", RuleConstant.NEXT_PAGE_RULE);
    /**
     * 章节翻页
     */
    private Boolean enableNext = true;
    /**
     * 章节黑名单链接（其中的链接不会加入到章节列表）
     */
    private Set<String> blackUrls;
    /**
     * 章节过滤
     */
    private Boolean filter = true;
    /**
     * 章节乱序重排
     */
    private Boolean sort;
    /**
     * 章节排序脚本
     */
    private String sortScript;
    /**
     * 章节逆序
     */
    private Boolean reverse = false;
    /**
     * 自动翻页
     */
    private Boolean autoNext = true;
    /**
     * 强制下一页，忽略标题相同 过滤器
     */
    private Boolean forceNext = false;

    /**
     * 目录规则是否有效
     *
     * @param rule 目录规则
     * @return true 有效
     */
    public static boolean isEffective(TocRule rule) {
        return rule != null && rule.isEffective();
    }

    /**
     * 是否允许章节翻页 规则必须存在
     *
     * @return /
     */
    public boolean isAllowNextPage() {
        return enableNext && CommonRule.isEffective(next);
    }

    /**
     * 章节规则是否有效
     *
     * @return /
     */
    @Override
    public boolean isEffective() {
        return CommonRule.isEffective(list) && CommonRule.hasRule(name) && CommonRule.hasRule(url);
    }

    public RequestParams getParams() {
        return params;
    }

    public void setParams(RequestParams params) {
        this.params = params;
    }

    public CommonRule getList() {
        return list;
    }

    public void setList(CommonRule list) {
        this.list = list;
    }

    public CommonRule getName() {
        return name;
    }

    public void setName(CommonRule name) {
        this.name = name;
    }

    public CommonRule getUrl() {
        return url;
    }

    public void setUrl(CommonRule url) {
        this.url = url;
    }

    public CommonRule getNext() {
        return next;
    }

    public void setNext(CommonRule next) {
        this.next = next;
    }

    public Boolean getEnableNext() {
        return enableNext;
    }

    public void setEnableNext(Boolean enableNext) {
        this.enableNext = enableNext;
    }

    public Set<String> getBlackUrls() {
        return blackUrls;
    }

    public void setBlackUrls(Set<String> blackUrls) {
        this.blackUrls = blackUrls;
    }

    public Boolean getFilter() {
        return filter;
    }

    public void setFilter(Boolean filter) {
        this.filter = filter;
    }

    public Boolean getSort() {
        return sort;
    }

    public void setSort(Boolean sort) {
        this.sort = sort;
    }

    public String getSortScript() {
        return sortScript;
    }

    public void setSortScript(String sortScript) {
        this.sortScript = sortScript;
    }

    public Boolean getReverse() {
        return reverse;
    }

    public void setReverse(Boolean reverse) {
        this.reverse = reverse;
    }

    public Boolean getAutoNext() {
        return autoNext;
    }

    public void setAutoNext(Boolean autoNext) {
        this.autoNext = autoNext;
    }

    public Boolean getForceNext() {
        return forceNext;
    }

    public void setForceNext(Boolean forceNext) {
        this.forceNext = forceNext;
    }
}
